#include <iostream>
#include <cstring>
using namespace std;

class String
{
	public :
		int m_len;
		char *m_str;
	public :
		/*默认构造函数*/
		String(const char* str == NULL);
		/*复制构造函数*/
		String(const String& other);
		/*重载赋值操作符*/
		String& operator=(const String& other);
		/*析构函数*/
		~String();

		/*重载输出操作符*/
		friend ostream& operator<<(ostream& out, const String& str);
		/*重载输入操作符*/
		friend istream& operator>>(istream& in, String& str);
		/*重载相加操作符*/
		friend String operator+(const String& lhs, const String& rhs);
		/*重载相等操作符*/
		friend bool operator==(const String& lhs, const String& rhs);

		/*重载下标操作符*/
		char& operator[](unsigned int index);
		/*重载下标操作符const类型*/
		const char& operator[](unsigned int index) const;
};

String :: String(const char* str)
{
	if(NULL == str)
	{
		m_len = 1;
		m_str = new char[m_len];
		*m_str = '\0';
	}
	else
	{
		m_len = strlen(str) + 1;
		m_str = new char[m_len];
		strcpy(m_str, str);
	}
}

String :: String(const String& other)
{
	m_len = strlen(other.m_str) + 1;
	m_str = new char[m_len];
	strcpy(m_str, other.m_str);
}

String& String :: operator=(const String& other)
{
	if(this != &other)
	{
		delete [] m_str;
		m_len = strlen(other.m_str) + 1;
		m_str = new char[m_len];
		strcpy(m_str, other.m_str);
	}
	cout << "<Operator=()>" << endl;

	return *this;
}

String :: ~String()
{
	cout << "<~String()>" << endl;
	delete [] m_str;
	m_str = NULL;
}

ostream& operator<<(ostream& out, const String& str)
{
	out << "<Operator<<()>" << endl << str.m_str;
	return out;
}

istream& operator>>(istream& in, String& str)
{
	cout << "<Operator>>()>" << endl;
	in >> str.m_str;
	return in;
}

String operator+(const String& lhs, const String& rhs)
{
	String temp;
	temp.m_str = new char[strlen(lhs.m_str) + strlen(rhs.m_str) + 1];
	temp.m_str = strcat(lhs.m_str, rhs.m_str);
	cout << "<Operator+()>" << endl;
	return temp;
}

bool operator==(const String& lhs, const String& rhs)
{
	cout << "<Operator==()>" << endl;
	if(strcmp(lhs.m_str, rhs.m_str) == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

char& String :: operator[](unsigned int index)
{
	static char c = '\0';

	if(index < m_len)
	{
		return m_str[index];
	}
	else
	{
		cout << "<Out of range>" << endl;
		return c;
	}
}

const char& operator[](unsigned int index) const
{
	static char c = '\0';

	if(index < m_len)
	{
		return m_str[index];
	}
	else
	{
		cout << "<Out of range>" << endl;
		return c;
	}
}

int main()
{
	String s1("Hello");
	cout << s1;

	String s2(s1);
	cout << s2;

	String s3;
	s3 = s1;
	cout << s3;

}
